package twoD.hofem;

/**
 * This class forms linearCombination R2->Rn of given basis functions,
 * coefficients and the dimension of range space.
 * 
 * @author Team-5
 * 
 */

public class LinearCombinationR2ToRn implements FunctionR2ToRn {

	private int n_;
	private double[] coefficients_;
	private FunctionBasisOnR2ToR basis_;

	/**
	 * Construct a LinearCombinationR2ToRn
	 * 
	 * @param n
	 *            The dimension of range space
	 * @param basis
	 *            Basis functions
	 */

	public LinearCombinationR2ToRn(int n, FunctionBasisOnR2ToR basis) {
		n_ = n;
		basis_ = basis;
	}

	/**
	 * Set the coefficients of LinearCombination
	 * 
	 * @param coefficients
	 *            The coefficients
	 * 
	 */

	public void setCoefficients(double... coefficients) {
		coefficients_ = coefficients;
	}

	public int getN() {

		return n_;
	}

	public double[][] jacobianAt(double xi1, double xi2) {

		double[][] result = new double[2][n_];

		for (int i = 0; i < n_; i++) {
			result[0][i] = coefficients_[i]
					* basis_.getBasisFunction(0).gradientAt(xi1, xi2)[0];
			result[1][i] = coefficients_[i]
					* basis_.getBasisFunction(0).gradientAt(xi1, xi2)[1];
			for (int j = 1; j < basis_.getDimension(); j++) {
				result[0][i] += coefficients_[i + j * n_]
						* basis_.getBasisFunction(j).gradientAt(xi1, xi2)[0];
				result[1][i] += coefficients_[i + j * n_]
						* basis_.getBasisFunction(j).gradientAt(xi1, xi2)[1];
			}
		}
		return result;
	}

	public double[] valueAt(double xi1, double xi2) {

		double[] result = new double[n_];

		for (int i = 0; i < n_; i++) {
			result[i] = coefficients_[i]
					* basis_.getBasisFunction(0).valueAt(xi1, xi2);
			for (int j = 1; j < basis_.getDimension(); j++) {
				result[i] += coefficients_[i + j * n_]
						* basis_.getBasisFunction(j).valueAt(xi1, xi2);
			}
		}
		return result;
	}

}
